package main.java;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.comet.CometEvent;
import org.apache.catalina.comet.CometProcessor;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public final class MessageExchangerServlet extends HttpServlet implements CometProcessor {

	private final String subscribe = "/subscribe";
	private final String unsubscribe = "/unsubscribe";
	private final BlockingQueue<CometEvent> events = new LinkedBlockingQueue<CometEvent>();

	@Override
	public void init() throws ServletException {
		super.init();
		getServletContext().setAttribute(
				MessageExchangerServlet.class.getName(), this);
	}

	@Override
	public void event(CometEvent evt) throws IOException, ServletException {
		HttpServletRequest request = evt.getHttpServletRequest();

		switch (evt.getEventType()) {
			case BEGIN: {
				if ("GET".equals(request.getMethod())) {
					evt.setTimeout(Integer.MAX_VALUE);
					events.offer(evt);
				} else {
					String message = request.getParameter("message");
					
					if (subscribe.equals(message)) {
						broadcast("connected");
						System.out.println("someone logged in!");
					} else if (unsubscribe.equals(message)) {
						broadcast("disconnected");
						System.out.println("someone logged out!");
						events.remove(evt);
					} else if (message != null) {
						broadcast(message);
						System.out.println("broadcasting message!");
					}
					
					evt.close();
				}
			}
		}
	}

	public void broadcast(String message) throws IOException {
		Queue<CometEvent> q = new LinkedList<CometEvent>();
		events.drainTo(q);
		while (!q.isEmpty()) {
			CometEvent event = q.poll();
			HttpServletResponse resp = event.getHttpServletResponse();
			resp.setStatus(HttpServletResponse.SC_OK);
			resp.setContentType("text/html");
			resp.getWriter().write(message);
			event.close();
		}
	}
}